package com.cencat.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cencat.common.utils.PaginationHelper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.util.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cencat.common.enums.ErrorCode;
import com.cencat.common.exception.BusinessException;
import com.cencat.common.utils.BeanUtils;
import com.cencat.product.dto.ProductCreateDTO;
import com.cencat.product.dto.ProductQueryDTO;
import com.cencat.product.dto.ProductUpdateDTO;
import com.cencat.product.entity.Product;
import com.cencat.product.mapper.ProductMapper;
import com.cencat.product.service.ProductService;
import com.cencat.product.vo.ProductVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import com.cencat.common.utils.CencatStringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 产品服务实现类
 * 
 * @author cencat
 * @since 2024-01-01
 */
@Service
@Slf4j
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {

    @Autowired
    private ProductMapper productMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createProduct(ProductCreateDTO dto) throws BusinessException {
        log.info("创建产品，参数：{}", dto);
        
        // 参数校验
        if (dto == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 检查产品编码是否存在
        if (CencatStringUtils.isNotBlank(dto.getProductCode()) && checkProductCodeExists(dto.getProductCode(), null)) {
            throw new BusinessException(ErrorCode.PRODUCT_CODE_EXISTS);
        }
        
        // 检查产品名称是否存在
        if (checkProductNameExists(dto.getProductName(), null)) {
            throw new BusinessException(ErrorCode.PRODUCT_NAME_EXISTS);
        }
        
        // 生成产品编码（如果未提供）
        if (CencatStringUtils.isBlank(dto.getProductCode())) {
            dto.setProductCode(generateProductCode("PRD"));
        }
        
        // 创建产品实体
        Product product = new Product();
        BeanUtils.copyProperties(dto, product);
        product.setCreateTime(LocalDateTime.now());
        product.setUpdateTime(LocalDateTime.now());
        product.setStatus(Product.ProductStatus.DRAFT);
        product.setAuditStatus(Product.AuditStatus.PENDING);
        product.setDeleted(0);
        
        // 设置默认值
        if (product.getSalesCount() == null) {
            product.setSalesCount(0);
        }
        if (product.getViewCount() == null) {
            product.setViewCount(0);
        }
        if (product.getFavoriteCount() == null) {
            product.setFavoriteCount(0);
        }
        if (product.getCommentCount() == null) {
            product.setCommentCount(0);
        }
        if (product.getRating() == null) {
            product.setRating(BigDecimal.ZERO);
        }
        if (product.getSortOrder() == null) {
            product.setSortOrder(0);
        }
        
        // 保存产品
        int result = productMapper.insert(product);
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        log.info("产品创建成功，产品ID：{}", product.getId());
        return product.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateProduct(ProductUpdateDTO dto) throws BusinessException {
        log.info("更新产品，参数：{}", dto);
        
        // 参数校验
        if (dto == null || dto.getId() == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 检查产品是否存在
        Product existingProduct = productMapper.selectById(dto.getId());
        if (existingProduct == null || existingProduct.getDeleted() != null && existingProduct.getDeleted() == 1) {
            throw new BusinessException(ErrorCode.PRODUCT_NOT_EXISTS);
        }
        
        // 检查产品编码是否存在（排除当前产品）
        if (CencatStringUtils.isNotBlank(dto.getProductCode()) && checkProductCodeExists(dto.getProductCode(), dto.getId())) {
            throw new BusinessException(ErrorCode.PRODUCT_CODE_EXISTS);
        }
        
        // 检查产品名称是否存在（排除当前产品）
        if (CencatStringUtils.isNotBlank(dto.getProductName()) && checkProductNameExists(dto.getProductName(), dto.getId())) {
            throw new BusinessException(ErrorCode.PRODUCT_NAME_EXISTS);
        }
        
        // 更新产品信息
        Product product = new Product();
        BeanUtils.copyProperties(dto, product);
        product.setUpdateTime(LocalDateTime.now());
        
        int result = productMapper.updateById(product);
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        log.info("产品更新成功，产品ID：{}", dto.getId());
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteProduct(Long id) throws BusinessException {
        log.info("删除产品，产品ID：{}", id);
        
        // 参数校验
        if (id == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 检查产品是否存在
        Product product = productMapper.selectById(id);
        if (product == null || product.getDeleted() != null && product.getDeleted() == 1) {
            throw new BusinessException(ErrorCode.PRODUCT_NOT_EXISTS);
        }
        
        // 逻辑删除
        product.setDeleted(1);
        product.setUpdateTime(LocalDateTime.now());
        
        int result = productMapper.updateById(product);
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        log.info("产品删除成功，产品ID：{}", id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchDeleteProducts(List<Long> ids) throws BusinessException {
        log.info("批量删除产品，产品ID列表：{}", ids);
        
        // 参数校验
        if (CollectionUtils.isEmpty(ids)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 批量删除
        String idsStr = ids.stream().map(String::valueOf).collect(Collectors.joining(","));
        int result = productMapper.batchDelete(idsStr, getCurrentUserId());
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        log.info("产品批量删除成功，删除数量：{}", result);
        return true;
    }

    @Override
    public Product getProductById(Long id) throws BusinessException {
        // 参数校验
        if (id == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        Product product = productMapper.selectById(id);
        if (product == null || product.getDeleted() != null && product.getDeleted() == 1) {
            throw new BusinessException(ErrorCode.PRODUCT_NOT_EXISTS);
        }
        
        return product;
    }

    @Override
    public Product getProductByCode(String productCode) throws BusinessException {
        // 参数校验
        if (CencatStringUtils.isBlank(productCode)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        Product product = productMapper.selectByProductCode(productCode);
        if (product == null) {
            throw new BusinessException(ErrorCode.PRODUCT_NOT_EXISTS);
        }
        
        return product;
    }

    @Override
    public ProductVO getProductDetail(Long id) throws BusinessException {
        // 参数校验
        if (id == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        ProductVO productVO = productMapper.selectProductDetail(id);
        if (productVO == null) {
            throw new BusinessException(ErrorCode.PRODUCT_NOT_EXISTS);
        }
        
        // 更新浏览数量
        updateProductViewCount(id);
        
        return productVO;
    }

    @Override
    public IPage<ProductVO> getProductPage(ProductQueryDTO queryDTO) throws BusinessException {
        // 参数校验
        if (queryDTO == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 设置默认分页参数
        if (queryDTO.getPageNum() == null || queryDTO.getPageNum() <= 0) {
            queryDTO.setPageNum(1);
        }
        if (queryDTO.getPageSize() == null || queryDTO.getPageSize() <= 0) {
            queryDTO.setPageSize(10);
        }
        
        // 构建分页查询参数
        PaginationHelper.PageQuery pageQuery = new PaginationHelper.PageQuery();
        pageQuery.setCurrent(queryDTO.getPageNum());
        pageQuery.setSize(queryDTO.getPageSize());
        
        // 构建查询条件
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_deleted", 0);
        
        if (StringUtils.hasText(queryDTO.getProductName())) {
            queryWrapper.like("product_name", queryDTO.getProductName());
        }
        
        if (StringUtils.hasText(queryDTO.getProductCode())) {
            queryWrapper.like("product_code", queryDTO.getProductCode());
        }
        
        if (queryDTO.getCategoryId() != null) {
            queryWrapper.eq("category_id", queryDTO.getCategoryId());
        }
        
        if (queryDTO.getBrandId() != null) {
            queryWrapper.eq("brand_id", queryDTO.getBrandId());
        }
        
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq("status", queryDTO.getStatus());
        }
        
        queryWrapper.orderByDesc("create_time");
        
        // 执行分页查询并转换为VO
        return PaginationHelper.executePage(pageQuery, queryWrapper, productMapper, this::convertToVO);
    }

    @Override
    public List<ProductVO> getProductList(ProductQueryDTO queryDTO) throws BusinessException {
        // 参数校验
        if (queryDTO == null) {
            queryDTO = new ProductQueryDTO();
        }
        
        // 设置不分页
        queryDTO.setPageNum(null);
        queryDTO.setPageSize(null);
        
        // 查询数据
        IPage<ProductVO> page = new Page<>(1, Integer.MAX_VALUE);
        IPage<ProductVO> result = productMapper.selectProductPage(page, queryDTO);
        
        return result.getRecords();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean onShelfProduct(Long id) throws BusinessException {
        log.info("上架产品，产品ID：{}", id);
        
        // 参数校验
        if (id == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 检查产品是否存在
        Product product = getProductById(id);
        
        // 检查产品状态
        if (product.getStatus() == Product.ProductStatus.ON_SHELF) {
            throw new BusinessException(ErrorCode.PRODUCT_ALREADY_ON_SHELF);
        }
        
        // 检查审核状态
        if (product.getAuditStatus() != Product.AuditStatus.APPROVED) {
            throw new BusinessException(ErrorCode.PRODUCT_NOT_APPROVED);
        }
        
        // 更新状态
        product.setStatus(Product.ProductStatus.ON_SHELF);
        product.setShelfTime(LocalDateTime.now());
        product.setUpdateTime(LocalDateTime.now());
        
        int result = productMapper.updateById(product);
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        log.info("产品上架成功，产品ID：{}", id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean offShelfProduct(Long id) throws BusinessException {
        log.info("下架产品，产品ID：{}", id);
        
        // 参数校验
        if (id == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 检查产品是否存在
        Product product = getProductById(id);
        
        // 检查产品状态
        if (product.getStatus() == Product.ProductStatus.OFF_SHELF) {
            throw new BusinessException(ErrorCode.PRODUCT_ALREADY_OFF_SHELF);
        }
        
        // 更新状态
        product.setStatus(Product.ProductStatus.OFF_SHELF);
        product.setOffShelfTime(LocalDateTime.now());
        product.setUpdateTime(LocalDateTime.now());
        
        int result = productMapper.updateById(product);
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        log.info("产品下架成功，产品ID：{}", id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchOnShelfProducts(List<Long> ids) throws BusinessException {
        log.info("批量上架产品，产品ID列表：{}", ids);
        
        // 参数校验
        if (CollectionUtils.isEmpty(ids)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 批量上架
        String idsStr = ids.stream().map(String::valueOf).collect(Collectors.joining(","));
        int result = productMapper.batchOnShelf(idsStr, getCurrentUserId());
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        log.info("产品批量上架成功，上架数量：{}", result);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchOffShelfProducts(List<Long> ids) throws BusinessException {
        log.info("批量下架产品，产品ID列表：{}", ids);
        
        // 参数校验
        if (CollectionUtils.isEmpty(ids)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 批量下架
        String idsStr = ids.stream().map(String::valueOf).collect(Collectors.joining(","));
        int result = productMapper.batchOffShelf(idsStr, getCurrentUserId());
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        log.info("产品批量下架成功，下架数量：{}", result);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean auditProduct(Long id, Product.AuditStatus auditStatus, String auditRemark) throws BusinessException {
        log.info("审核产品，产品ID：{}，审核状态：{}，审核备注：{}", id, auditStatus, auditRemark);
        
        // 参数校验
        if (id == null || auditStatus == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 检查产品是否存在
        Product product = getProductById(id);
        
        // 更新审核信息
        product.setAuditStatus(auditStatus);
        product.setAuditTime(LocalDateTime.now());
        product.setAuditorId(getCurrentUserId());
        product.setAuditRemark(auditRemark);
        product.setUpdateTime(LocalDateTime.now());
        
        int result = productMapper.updateById(product);
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        log.info("产品审核成功，产品ID：{}", id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchAuditProducts(List<Long> ids, Product.AuditStatus auditStatus, String auditRemark) throws BusinessException {
        log.info("批量审核产品，产品ID列表：{}，审核状态：{}，审核备注：{}", ids, auditStatus, auditRemark);
        
        // 参数校验
        if (CollectionUtils.isEmpty(ids) || auditStatus == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 批量审核
        String idsStr = ids.stream().map(String::valueOf).collect(Collectors.joining(","));
        int result = productMapper.batchUpdateAuditStatus(idsStr, auditStatus, getCurrentUserId(), auditRemark);
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        log.info("产品批量审核成功，审核数量：{}", result);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateProductStock(Long id, Integer stockQuantity) throws BusinessException {
        log.info("更新产品库存，产品ID：{}，库存数量：{}", id, stockQuantity);
        
        // 参数校验
        if (id == null || stockQuantity == null || stockQuantity < 0) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 检查产品是否存在
        getProductById(id);
        
        // 更新库存
        int result = productMapper.updateStock(id, stockQuantity, getCurrentUserId());
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        log.info("产品库存更新成功，产品ID：{}", id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean increaseProductStock(Long id, Integer quantity) throws BusinessException {
        log.info("增加产品库存，产品ID：{}，增加数量：{}", id, quantity);
        
        // 参数校验
        if (id == null || quantity == null || quantity <= 0) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 检查产品是否存在
        getProductById(id);
        
        // 增加库存
        int result = productMapper.increaseStock(id, quantity, getCurrentUserId());
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        log.info("产品库存增加成功，产品ID：{}", id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean decreaseProductStock(Long id, Integer quantity) throws BusinessException {
        log.info("减少产品库存，产品ID：{}，减少数量：{}", id, quantity);
        
        // 参数校验
        if (id == null || quantity == null || quantity <= 0) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 检查产品是否存在
        Product product = getProductById(id);
        
        // 检查库存是否充足
        if (product.getStockQuantity() < quantity) {
            throw new BusinessException(ErrorCode.INSUFFICIENT_STOCK);
        }
        
        // 减少库存
        int result = productMapper.decreaseStock(id, quantity, getCurrentUserId());
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        log.info("产品库存减少成功，产品ID：{}", id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateProductSalesCount(Long id, Integer salesCount) throws BusinessException {
        // 参数校验
        if (id == null || salesCount == null || salesCount <= 0) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 检查产品是否存在
        getProductById(id);
        
        // 更新销售数量
        int result = productMapper.updateSalesCount(id, salesCount);
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateProductViewCount(Long id) throws BusinessException {
        // 参数校验
        if (id == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 更新浏览数量
        int result = productMapper.updateViewCount(id);
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateProductFavoriteCount(Long id, Integer favoriteCount) throws BusinessException {
        // 参数校验
        if (id == null || favoriteCount == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 检查产品是否存在
        getProductById(id);
        
        // 更新收藏数量
        int result = productMapper.updateFavoriteCount(id, favoriteCount);
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateProductRating(Long id, BigDecimal rating, Integer commentCount) throws BusinessException {
        // 参数校验
        if (id == null || rating == null || commentCount == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 检查产品是否存在
        getProductById(id);
        
        // 更新评分
        int result = productMapper.updateRating(id, rating, commentCount);
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        return true;
    }

    @Override
    public List<ProductVO> getRecommendedProducts(Integer limit) throws BusinessException {
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        
        List<Product> products = productMapper.selectRecommendedProducts(limit);
        return convertToVOList(products);
    }

    @Override
    public List<ProductVO> getHotProducts(Integer limit) throws BusinessException {
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        
        List<Product> products = productMapper.selectHotProducts(limit);
        return convertToVOList(products);
    }

    @Override
    public List<ProductVO> getNewProducts(Integer limit) throws BusinessException {
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        
        List<Product> products = productMapper.selectNewProducts(limit);
        return convertToVOList(products);
    }

    @Override
    public List<ProductVO> getSpecialProducts(Integer limit) throws BusinessException {
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        
        List<Product> products = productMapper.selectSpecialProducts(limit);
        return convertToVOList(products);
    }

    @Override
    public List<ProductVO> getProductsByMerchantId(Long merchantId) throws BusinessException {
        if (merchantId == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        List<Product> products = productMapper.selectByMerchantId(merchantId);
        return convertToVOList(products);
    }

    @Override
    public List<ProductVO> getProductsByCategoryId(Long categoryId) throws BusinessException {
        if (categoryId == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        List<Product> products = productMapper.selectByCategoryId(categoryId);
        return convertToVOList(products);
    }

    @Override
    public List<ProductVO> getProductsByBrandId(Long brandId) throws BusinessException {
        if (brandId == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        List<Product> products = productMapper.selectByBrandId(brandId);
        return convertToVOList(products);
    }

    @Override
    public List<ProductVO> getProductsByPriceRange(BigDecimal minPrice, BigDecimal maxPrice) throws BusinessException {
        if (minPrice == null || maxPrice == null || minPrice.compareTo(maxPrice) > 0) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        List<Product> products = productMapper.selectByPriceRange(minPrice, maxPrice);
        return convertToVOList(products);
    }

    @Override
    public List<ProductVO> searchProducts(String keyword, Integer limit) throws BusinessException {
        if (CencatStringUtils.isBlank(keyword)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        if (limit == null || limit <= 0) {
            limit = 20;
        }
        
        List<Product> products = productMapper.searchProducts(keyword, limit);
        return convertToVOList(products);
    }

    @Override
    public List<ProductVO> getRelatedProducts(Long productId, Integer limit) throws BusinessException {
        if (productId == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        
        List<Product> products = productMapper.selectRelatedProducts(productId, limit);
        return convertToVOList(products);
    }

    @Override
    public List<ProductVO> getExpiringProducts(Integer days) throws BusinessException {
        if (days == null || days <= 0) {
            days = 7; // 默认7天
        }
        
        List<Product> products = productMapper.selectExpiringProducts(days);
        return convertToVOList(products);
    }

    @Override
    public List<ProductVO> getExpiredProducts() throws BusinessException {
        List<Product> products = productMapper.selectExpiredProducts();
        return convertToVOList(products);
    }

    @Override
    public List<ProductVO> getLowStockProducts() throws BusinessException {
        List<Product> products = productMapper.selectLowStockProducts();
        return convertToVOList(products);
    }

    @Override
    public List<ProductVO> getSoldOutProducts() throws BusinessException {
        List<Product> products = productMapper.selectSoldOutProducts();
        return convertToVOList(products);
    }

    @Override
    public Long countTotalProducts() throws BusinessException {
        return productMapper.countTotal();
    }

    @Override
    public Long countProductsByStatus(Product.ProductStatus status) throws BusinessException {
        if (status == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        return productMapper.countByStatus(status);
    }

    @Override
    public Long countProductsByType(Product.ProductType productType) throws BusinessException {
        if (productType == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        return productMapper.countByProductType(productType);
    }

    @Override
    public Long countProductsByAuditStatus(Product.AuditStatus auditStatus) throws BusinessException {
        if (auditStatus == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        return productMapper.countByAuditStatus(auditStatus);
    }

    @Override
    public Long countLowStockProducts() throws BusinessException {
        return productMapper.countLowStockProducts();
    }

    @Override
    public Long countSoldOutProducts() throws BusinessException {
        return productMapper.countSoldOutProducts();
    }

    @Override
    public Map<String, Object> getMerchantProductStats(Long merchantId) throws BusinessException {
        if (merchantId == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        return productMapper.selectMerchantProductStats(merchantId);
    }

    @Override
    public Map<String, Object> getCategoryProductStats(Long categoryId) throws BusinessException {
        if (categoryId == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        return productMapper.selectCategoryProductStats(categoryId);
    }

    @Override
    public Map<String, Object> getBrandProductStats(Long brandId) throws BusinessException {
        if (brandId == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        return productMapper.selectBrandProductStats(brandId);
    }

    @Override
    public List<Map<String, Object>> getProductSalesStats(LocalDateTime startTime, LocalDateTime endTime) throws BusinessException {
        if (startTime == null || endTime == null || startTime.isAfter(endTime)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        return productMapper.selectProductSalesStats(startTime, endTime);
    }

    @Override
    public Map<String, Object> getProductStockStats() throws BusinessException {
        return productMapper.selectProductStockStats();
    }

    @Override
    public String generateProductCode(String prefix) throws BusinessException {
        if (CencatStringUtils.isBlank(prefix)) {
            prefix = "PRD";
        }
        
        // 获取当前日期
        String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        
        // 获取下一个序号
        String codePrefix = prefix + dateStr;
        Long sequence = productMapper.getNextProductCodeSequence(codePrefix, codePrefix.length());
        
        // 生成产品编码
        return String.format("%s%04d", codePrefix, sequence);
    }

    @Override
    public Boolean checkProductCodeExists(String productCode, Long excludeId) throws BusinessException {
        if (CencatStringUtils.isBlank(productCode)) {
            return false;
        }
        
        if (excludeId == null) {
            excludeId = 0L;
        }
        
        return productMapper.existsProductCode(productCode, excludeId);
    }

    @Override
    public Boolean checkProductNameExists(String productName, Long excludeId) throws BusinessException {
        if (CencatStringUtils.isBlank(productName)) {
            return false;
        }
        
        if (excludeId == null) {
            excludeId = 0L;
        }
        
        return productMapper.existsProductName(productName, excludeId);
    }

    @Override
    public String exportProducts(ProductQueryDTO queryDTO) throws BusinessException {
        try {
            // 查询产品数据
            List<ProductVO> products = getProductList(queryDTO);
            
            // 生成导出文件路径
            String fileName = "products_export_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")) + ".xlsx";
            String filePath = "/tmp/exports/" + fileName;
            
            // TODO: 实现Excel导出逻辑
            // 这里应该使用EasyExcel或POI来生成Excel文件
            log.info("导出产品数据，共{}条记录，文件路径: {}", products.size(), filePath);
            
            return filePath;
        } catch (Exception e) {
            log.error("导出产品数据失败", e);
            throw new BusinessException(ErrorCode.OPERATION_FAILED, "导出产品数据失败");
        }
    }

    @Override
    public Map<String, Object> importProducts(String filePath) throws BusinessException {
        try {
            // 参数校验
            if (CencatStringUtils.isBlank(filePath)) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "文件路径不能为空");
            }
            
            // TODO: 实现Excel导入逻辑
            // 这里应该使用EasyExcel或POI来读取Excel文件
            
            // 模拟导入结果
            Map<String, Object> result = Map.of(
                "totalCount", 0,
                "successCount", 0,
                "failCount", 0,
                "errorMessages", List.of()
            );
            
            log.info("导入产品数据完成，文件路径: {}, 结果: {}", filePath, result);
            
            return result;
        } catch (Exception e) {
            log.error("导入产品数据失败", e);
            throw new BusinessException(ErrorCode.OPERATION_FAILED, "导入产品数据失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long copyProduct(Long id, String newProductName, String newProductCode) throws BusinessException {
        log.info("复制产品，原产品ID：{}，新产品名称：{}，新产品编码：{}", id, newProductName, newProductCode);
        
        // 参数校验
        if (id == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "产品ID不能为空");
        }
        if (CencatStringUtils.isBlank(newProductName)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "新产品名称不能为空");
        }
        if (CencatStringUtils.isBlank(newProductCode)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "新产品编码不能为空");
        }
        
        // 检查原产品是否存在
        Product originalProduct = getProductById(id);
        
        // 检查新产品编码是否存在
        if (checkProductCodeExists(newProductCode, null)) {
            throw new BusinessException(ErrorCode.PRODUCT_CODE_EXISTS, "产品编码已存在");
        }
        
        // 检查新产品名称是否存在
        if (checkProductNameExists(newProductName, null)) {
            throw new BusinessException(ErrorCode.PRODUCT_NAME_EXISTS, "产品名称已存在");
        }
        
        // 复制产品
        Product newProduct = new Product();
        BeanUtils.copyProperties(originalProduct, newProduct);
        newProduct.setId(null);
        newProduct.setProductCode(newProductCode);
        newProduct.setProductName(newProductName);
        newProduct.setStatus(Product.ProductStatus.DRAFT); // 复制的产品默认为草稿状态
        newProduct.setAuditStatus(Product.AuditStatus.PENDING); // 待审核
        newProduct.setCreateTime(LocalDateTime.now());
        newProduct.setUpdateTime(LocalDateTime.now());
        newProduct.setCreateBy(getCurrentUserId());
        newProduct.setUpdateBy(getCurrentUserId());
        
        // 重置统计数据
        newProduct.setSalesCount(0);
        newProduct.setViewCount(0);
        newProduct.setFavoriteCount(0);
        newProduct.setCommentCount(0);
        newProduct.setRating(BigDecimal.ZERO);
        
        // 保存新产品
        int result = productMapper.insert(newProduct);
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED, "复制产品失败");
        }
        
        log.info("产品复制成功，新产品ID：{}", newProduct.getId());
        return newProduct.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean setProductRecommended(Long id, Boolean isRecommended) throws BusinessException {
        return updateProductFlag(id, "is_recommended", isRecommended);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean setProductHot(Long id, Boolean isHot) throws BusinessException {
        return updateProductFlag(id, "is_hot", isHot);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean setProductNew(Long id, Boolean isNew) throws BusinessException {
        return updateProductFlag(id, "is_new", isNew);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean setProductSpecial(Long id, Boolean isSpecial) throws BusinessException {
        return updateProductFlag(id, "is_special", isSpecial);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchUpdateProductStatus(List<Long> ids, Product.ProductStatus status) throws BusinessException {
        // 参数校验
        if (CollectionUtils.isEmpty(ids) || status == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 批量更新状态
        String idsStr = ids.stream().map(String::valueOf).collect(Collectors.joining(","));
        int result = productMapper.batchUpdateStatus(idsStr, status, getCurrentUserId());
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchUpdateProductPrice(List<Long> ids, BigDecimal salePrice, BigDecimal marketPrice) throws BusinessException {
        // 参数校验
        if (CollectionUtils.isEmpty(ids)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        if (salePrice != null && salePrice.compareTo(BigDecimal.ZERO) < 0) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "销售价格不能为负数");
        }
        if (marketPrice != null && marketPrice.compareTo(BigDecimal.ZERO) < 0) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "市场价格不能为负数");
        }
        
        // 批量更新价格
        for (Long id : ids) {
            Product updateProduct = new Product();
            updateProduct.setId(id);
            if (salePrice != null) {
                updateProduct.setSalePrice(salePrice);
            }
            if (marketPrice != null) {
                updateProduct.setMarketPrice(marketPrice);
            }
            updateProduct.setUpdateTime(LocalDateTime.now());
            updateProduct.setUpdateBy(getCurrentUserId());
            
            int result = productMapper.updateById(updateProduct);
            if (result <= 0) {
                throw new BusinessException(ErrorCode.OPERATION_FAILED, "更新产品价格失败，产品ID: " + id);
            }
        }
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchUpdateProductCategory(List<Long> ids, Long categoryId) throws BusinessException {
        // 参数校验
        if (CollectionUtils.isEmpty(ids) || categoryId == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 批量更新分类
        for (Long id : ids) {
            Product updateProduct = new Product();
            updateProduct.setId(id);
            updateProduct.setCategoryId(categoryId);
            updateProduct.setUpdateTime(LocalDateTime.now());
            updateProduct.setUpdateBy(getCurrentUserId());
            
            int result = productMapper.updateById(updateProduct);
            if (result <= 0) {
                throw new BusinessException(ErrorCode.OPERATION_FAILED, "更新产品分类失败，产品ID: " + id);
            }
        }
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchUpdateProductBrand(List<Long> ids, Long brandId) throws BusinessException {
        // 参数校验
        if (CollectionUtils.isEmpty(ids) || brandId == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 批量更新品牌
        for (Long id : ids) {
            Product updateProduct = new Product();
            updateProduct.setId(id);
            updateProduct.setBrandId(brandId);
            updateProduct.setUpdateTime(LocalDateTime.now());
            updateProduct.setUpdateBy(getCurrentUserId());
            
            int result = productMapper.updateById(updateProduct);
            if (result <= 0) {
                throw new BusinessException(ErrorCode.OPERATION_FAILED, "更新产品品牌失败，产品ID: " + id);
            }
        }
        
        return true;
    }

    /**
     * 转换产品列表为VO列表
     * 
     * @param products 产品列表
     * @return VO列表
     */
    private List<ProductVO> convertToVOList(List<Product> products) {
        if (CollectionUtils.isEmpty(products)) {
            return List.of();
        }
        
        return products.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    /**
     * 转换产品为VO
     * 
     * @param product 产品
     * @return VO
     */
    private ProductVO convertToVO(Product product) {
        if (product == null) {
            return null;
        }
        
        ProductVO vo = new ProductVO();
        BeanUtils.copyProperties(product, vo);
        
        // 设置状态描述
        if (product.getStatus() != null) {
            vo.setStatusDesc(product.getStatus().getDescription());
        }
        if (product.getProductType() != null) {
            vo.setProductTypeDesc(product.getProductType().getDescription());
        }
        if (product.getAuditStatus() != null) {
            vo.setAuditStatusDesc(product.getAuditStatus().getDescription());
        }
        
        // TODO: 设置关联信息（分类、品牌、商家等）
        
        return vo;
    }

    /**
     * 更新产品标志位
     * 
     * @param id 产品ID
     * @param fieldName 字段名
     * @param value 值
     * @return 是否成功
     */
    private Boolean updateProductFlag(Long id, String fieldName, Boolean value) throws BusinessException {
        // 参数校验
        if (id == null || CencatStringUtils.isBlank(fieldName) || value == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        // 检查产品是否存在
        Product product = getProductById(id);
        
        // 更新标志位
        Product updateProduct = new Product();
        updateProduct.setId(id);
        updateProduct.setUpdateTime(LocalDateTime.now());
        updateProduct.setUpdateBy(getCurrentUserId());
        
        // 根据字段名设置值
        switch (fieldName) {
            case "is_recommended":
                updateProduct.setIsRecommended(value);
                break;
            case "is_hot":
                updateProduct.setIsHot(value);
                break;
            case "is_new":
                updateProduct.setIsNew(value);
                break;
            case "is_special":
                updateProduct.setIsSpecial(value);
                break;
            default:
                throw new BusinessException(ErrorCode.PARAM_ERROR);
        }
        
        int result = productMapper.updateById(updateProduct);
        if (result <= 0) {
            throw new BusinessException(ErrorCode.OPERATION_FAILED);
        }
        
        return true;
    }

    /**
     * 获取当前用户ID
     * 
     * @return 用户ID
     */
    private Long getCurrentUserId() {
        // TODO: 从安全上下文获取当前用户ID
        return 1L;
    }
}